package com.homedo.microservice.open.service.gateway.manager.web.gateway.service;

import com.google.common.collect.Lists;
import com.homedo.common.bean.data.enums.ResponseEnum;
import com.homedo.common.bean.vo.Pagination;
import com.homedo.common.bean.vo.context.UserContext;
import com.homedo.common.dao.bean.po.base.BasePo;
import com.homedo.common.exception.HomedoException;
import com.homedo.common.service.BaseService;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.enums.forrouteserviceurl.StatusEnum4RouteServiceUrl;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.po.RouteServiceUrl;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.po.enhanced.RouteServiceEnhanced;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.po.enhanced.RouteServiceUrlEnhanced;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.query.RouteServiceUrlQuery;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.persistence.dao.RouteServiceUrlDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 作者 jgshun
 * @date 创建时间 2018年09月18日 11时30分20秒
 */
@Service
public class RouteServiceUrlService extends BaseService<RouteServiceUrl> {
    @Autowired
    private RouteServiceUrlDao routeServiceUrlDao;
    @Autowired
    private RouteServiceService routeServiceService;


    @Override
    public List<RouteServiceUrlEnhanced> getEnhanceds(List<?> ids, UserContext userContext) {
        List<RouteServiceUrl> routeServiceUrls = routeServiceUrlDao.getListByIds(ids, RouteServiceUrl.class);

        if (!Detect.notEmpty(routeServiceUrls)) {
            return null;
        }

        return this.convent2Enhanceds(routeServiceUrls);
    }


    @Override
    public List<RouteServiceUrlEnhanced> getEnhanceds4Active(List<?> ids, UserContext userContext) {
        List<RouteServiceUrl> routeServiceUrls = routeServiceUrlDao.getListByIdsGreaterThanMark0(ids, RouteServiceUrl.class);

        if (!Detect.notEmpty(routeServiceUrls)) {
            return null;
        }

        return this.convent2Enhanceds(routeServiceUrls);
    }


    @Override
    public List<RouteServiceUrlEnhanced> convent2Enhanceds(List<? extends BasePo> pos) {
        List<RouteServiceUrl> routeServiceUrls = (List<RouteServiceUrl>) pos;
        List<RouteServiceUrlEnhanced> routeServiceUrlEnhanceds = Lists.newArrayList();
        routeServiceUrls.forEach(e -> routeServiceUrlEnhanceds.add(new RouteServiceUrlEnhanced(e)));
        return routeServiceUrlEnhanceds;
    }


    public List<RouteServiceUrlEnhanced> getEnhanceds4Services(List<String> serviceIds, UserContext userContext) {
        List<RouteServiceUrl> routeServiceUrls = routeServiceUrlDao.getListByServiceIds(serviceIds);

        if (!Detect.notEmpty(routeServiceUrls)) {
            return null;
        }

        return this.convent2Enhanceds(routeServiceUrls);
    }

    public Pagination<RouteServiceUrlEnhanced> getPagination(RouteServiceUrlQuery routeServiceUrlQuery, Pagination<RouteServiceUrlEnhanced> pagination, UserContext userContext) {
        Pagination<RouteServiceUrl> routeServiceUrlPagination = routeServiceUrlDao.getPagination(routeServiceUrlQuery, pagination.copy());

        pagination.setCount(routeServiceUrlPagination.getCount());
        if (!Detect.notEmpty(routeServiceUrlPagination.getItems())) {
            return pagination;
        }

        pagination.setItems(this.convent2Enhanceds(routeServiceUrlPagination.getItems()));

        return pagination;
    }

    public RouteServiceUrl saveRouteServiceUrl(RouteServiceUrl routeServiceUrl, UserContext userContext) {
        this.checkSave(routeServiceUrl);

        routeServiceUrl.setCreateTime(new Date());
        routeServiceUrl.setUpdateTime(new Date());

        routeServiceUrl = routeServiceUrlDao.saveSelective(routeServiceUrl);

        return routeServiceUrl;
    }

    private void checkSave(RouteServiceUrl routeServiceUrl) {
        if (!Detect.notEmpty(routeServiceUrl.getServiceId()) || !Detect.notEmpty(routeServiceUrl.getUrl())
                || routeServiceUrl.getStatus() == null) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
        String url = routeServiceUrl.getUrl();

        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }

        if (url.split(":").length != 3) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
        if (!Detect.isNumeric(url.split(":")[2])) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
    }

    public RouteServiceUrl updateRouteServiceUrl(Integer id, String url, Short status, String comment, UserContext userContext) {
        RouteServiceUrl routeServiceUrl = routeServiceUrlDao.getById(id);

        if (Detect.notEmpty(url)) {
            routeServiceUrl.setUrl(url);
        }

        if (status != null && StatusEnum4RouteServiceUrl.getStatusEnumByCode(status) != null) {
            routeServiceUrl.setStatus(status.intValue());
        }
        if (Detect.notEmpty(comment)) {
            routeServiceUrl.setComment(comment);
        }

        routeServiceUrl.setUpdateTime(new Date());

        routeServiceUrlDao.updateByPrimaryKeySelective(routeServiceUrl);

        return routeServiceUrl;
    }

    public List<RouteServiceUrlEnhanced> appendEnhancedRouteService(List<RouteServiceUrlEnhanced> routeServiceUrlEnhanceds, UserContext userContext) {
        List<String> serviceIds = routeServiceUrlEnhanceds.stream().map(RouteServiceUrlEnhanced::getRouteServiceEnhanced)
                .collect(Collectors.toList()).stream().map(RouteServiceEnhanced::getId).collect(Collectors.toList());

        List<RouteServiceEnhanced> routeServiceEnhanceds = routeServiceService.getEnhanceds(serviceIds, userContext);

        if (!Detect.notEmpty(routeServiceEnhanceds)) {
            return routeServiceUrlEnhanceds;
        }

        this.appendEnhancedRouteService(routeServiceUrlEnhanceds, routeServiceEnhanceds, userContext);

        return routeServiceUrlEnhanceds;
    }

    private void appendEnhancedRouteService(List<RouteServiceUrlEnhanced> routeServiceUrlEnhanceds, List<RouteServiceEnhanced> routeServiceEnhanceds, UserContext userContext) {
        routeServiceUrlEnhanceds.forEach(e -> this.appendEnhancedRouteService(e, routeServiceEnhanceds, userContext));
    }

    private void appendEnhancedRouteService(RouteServiceUrlEnhanced routeServiceUrlEnhanced, List<RouteServiceEnhanced> routeServiceEnhanceds, UserContext userContext) {
        for (RouteServiceEnhanced routeServiceEnhanced : routeServiceEnhanceds) {
            if (routeServiceUrlEnhanced.getRouteServiceEnhanced() != null && routeServiceUrlEnhanced.getRouteServiceEnhanced().getId().equals(routeServiceEnhanced.getId())) {
                routeServiceUrlEnhanced.setRouteServiceEnhanced(routeServiceEnhanced);
                break;
            }
        }
    }

}
